package com.blensmile.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DrawFilter;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.SweepGradient;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;

import com.blensmile.R;
import com.blensmile.utils.DensityUtils;
import com.blensmile.utils.LogUtils;

/**
 * Created by Blensmile on 2017/2/5.
 */
public class TalkMateLoadingView extends View {
    // 波纹颜色
    private static final int WAVE_PAINT_COLOR = 0xffff6c8d;
    private static final int CIRCLE_COLOR = 0xffFC4F75;
    private static final int BACK_COLOR = 0xffbfbcbc;
    // y = Asin(wx+b)+h
    private static final float STRETCH_FACTOR_A = 0.02f;
    private static final int OFFSET_Y = 0;
    // 第一条水波移动速度
    private static final int TRANSLATE_X_SPEED_ONE = 10;
    // 第二条水波移动速度
    private static final int TRANSLATE_X_SPEED_TWO = 8;
    private final Paint bgPaint;
    private RectF oval = new RectF();
    private Rect drawableBounds = new Rect();

    private float mCycleFactorW;

    private int mTotalWidth, mTotalHeight;
    private float[] mYPositions;
    private float[] mResetOneYPositions;
    private float[] mResetTwoYPositions;
    private int mXOffsetSpeedOne;
    private int mXOffsetSpeedTwo;
    private int mXOneOffset;
    private int mXTwoOffset;

    private Paint mWavePaint;
    private DrawFilter mDrawFilter;

    private byte progress = 20;//百分之几
    private float waveFactor = 1f;
    private int baseWave = 100;//应该换成dp，一遍统一
    private int pointMount ;
    private int currentDegree;//当前角度
    private Paint paint;
    private float strokeWidth = 5;
    private Drawable drawable;
    private float speedFactor = 2;
    private int drawableGap = 4;

    public TalkMateLoadingView(Context context) {
        this(context,null);
    }

    public TalkMateLoadingView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // 将dp转化为px，用于控制不同分辨率上移动速度基本一致
        mXOffsetSpeedOne = DensityUtils.dip2px(context, TRANSLATE_X_SPEED_ONE);
        mXOffsetSpeedTwo = DensityUtils.dip2px(context, TRANSLATE_X_SPEED_TWO);

        // 初始绘制波纹的画笔
        mWavePaint = new Paint();
        // 去除画笔锯齿
        mWavePaint.setAntiAlias(true);
        // 设置风格为实线
        mWavePaint.setStyle(Paint.Style.FILL);
        // 设置画笔颜色
        mWavePaint.setColor(WAVE_PAINT_COLOR);
//        mWavePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
        mDrawFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
         paint = new Paint();
        paint.setAntiAlias(true);
        paint.setColor(Color.RED);
        paint.setStrokeWidth(strokeWidth); // 线宽
        paint.setStyle(Paint.Style.STROKE);
        bgPaint = new Paint();
        bgPaint.setColor(BACK_COLOR);
        bgPaint.setStyle(Paint.Style.FILL);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 从canvas层面去除绘制时锯齿
        canvas.setDrawFilter(mDrawFilter);
        resetPositonY();
        int heigt = progress*drawableBounds.height()/100;
        canvas.drawRect(drawableBounds,bgPaint);

        int bounds = drawableBounds.width()-1;
        for (int i = 0,start = drawableBounds.left+1; i < bounds; i++,start++) {
            // 绘制第一条水波纹
            canvas.drawLine(start, checkHeight(drawableBounds.bottom - mResetOneYPositions[i] - heigt), start,
                    drawableBounds.bottom-1,
                    mWavePaint);

            // 绘制第二条水波纹
            canvas.drawLine(start, checkHeight(drawableBounds.bottom - mResetTwoYPositions[i] - heigt), start,
                    drawableBounds.bottom-1,
                    mWavePaint);
        }

        // 改变两条波纹的移动点
        mXOneOffset += mXOffsetSpeedOne;
        mXTwoOffset += mXOffsetSpeedTwo;

        // 如果已经移动到结尾处，则重头记录
        if (mXOneOffset >=pointMount) {
            mXOneOffset = 0;
        }
        if (mXTwoOffset > pointMount) {
            mXTwoOffset = 0;
        }

        drawable.draw(canvas);

        canvas.rotate(currentDegree,mTotalWidth/2,mTotalHeight/2);
        canvas.drawArc(oval, 0, 360, false, paint);

        currentDegree=(int)(currentDegree+10*speedFactor)%360;
        progress+=1;
        if(progress>100)
            progress = 0;
        postInvalidateDelayed(32);
    }

    private float checkHeight(float h){
        if(h>=drawableBounds.bottom){
            return drawableBounds.bottom-1;
        }else {
            return h>drawableBounds.top?h:drawableBounds.top+1;
        }
    }

    private void resetPositonY() {
        // mXOneOffset代表当前第一条水波纹要移动的距离
        int yOneInterval = mResetOneYPositions.length + mXOneOffset;
        // 使用System.arraycopy方式重新填充第一条波纹的数据
        if(yOneInterval<mYPositions.length){
            System.arraycopy(mYPositions, mXOneOffset, mResetOneYPositions, 0, mResetOneYPositions.length);
        }else {
            System.arraycopy(mYPositions, mXOneOffset, mResetOneYPositions, 0, mYPositions.length-mXOneOffset);
            System.arraycopy(mYPositions, 0, mResetOneYPositions, mYPositions.length-mXOneOffset, yOneInterval-mYPositions.length);
        }
        int yTwoInterval = mResetTwoYPositions.length + mXTwoOffset;
        if(yTwoInterval<mYPositions.length){
            System.arraycopy(mYPositions, mXTwoOffset, mResetTwoYPositions, 0, mResetTwoYPositions.length);
        }else {
            System.arraycopy(mYPositions, mXTwoOffset, mResetTwoYPositions, 0, mYPositions.length-mXTwoOffset);
            System.arraycopy(mYPositions, 0, mResetTwoYPositions, mYPositions.length-mXTwoOffset, yTwoInterval - mYPositions.length);
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        if(width != height){
            width = width<height?height=width:height;
        }
        setMeasuredDimension(width,height);
        LogUtils.b("onMeasure");
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        LogUtils.b("onLayout");
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        LogUtils.b("onSizeChanged");
        initDimens(w,h);
    }

    private void initDimens(int w,int h){
        mTotalWidth = w;
        mTotalHeight = h;

        oval.left = strokeWidth / 2; // 左边
        oval.top = strokeWidth / 2; // 上边
        oval.right = mTotalWidth - strokeWidth / 2; // 右边
        oval.bottom = mTotalHeight - strokeWidth / 2; // 下边

        SweepGradient rg = new SweepGradient(mTotalWidth/2,mTotalWidth/2,0x00ffffff,CIRCLE_COLOR);
        paint.setShader(rg);

        if(drawable == null) {
            drawable = getContext().getResources().getDrawable(R.drawable.talkmate_gray);
        }
        int dwidth = drawable.getIntrinsicWidth();
        int dheight = drawable.getIntrinsicHeight();
        double powd = Math.sqrt(dwidth*dwidth+dheight*dheight);
        float drawableRadius = mTotalWidth/2-drawableGap-strokeWidth;
        int bigRadius = mTotalWidth/2;
        int drawableW = (int)(drawableRadius*(dwidth/powd));
        int drawableH = (int)(drawableRadius*(dheight/powd));

        drawableBounds.left = bigRadius-drawableW;
        drawableBounds.top = bigRadius-drawableH;
        drawableBounds.right = bigRadius+drawableW;
        drawableBounds.bottom = bigRadius+drawableH;
        drawable.setBounds(drawableBounds);

        pointMount = (int)(baseWave * waveFactor);
        if(pointMount<drawableBounds.width()) {
            pointMount = drawableBounds.width();
        }
        // 用于保存原始波纹的y值
        mYPositions = new float[pointMount];

        // 将周期定为view总宽度
        mCycleFactorW = (float) (2 * Math.PI / pointMount);

        // 根据view总宽度得出所有对应的y值
        for (int i = 0; i < pointMount; i++) {
            mYPositions[i] = (float) (mTotalHeight*STRETCH_FACTOR_A * Math.sin(mCycleFactorW * i) + OFFSET_Y);
        }

        // 用于保存波纹一的y值
        mResetOneYPositions = new float[drawableBounds.width()];
        // 用于保存波纹二的y值
        mResetTwoYPositions = new float[drawableBounds.width()];
    }

    public byte getProgress() {
        return progress;
    }

    public void setProgress(byte progress) {
        if(progress<0){
            this.progress = 0;
        }else if (progress>100){
            this.progress = 100;
        }else {
            this.progress = progress;
        }
    }
}
